package stage;

/**
* Classe che implementa la Lista tramite puntantori impliciti
*
*@author Matteo Cuccato
*@author Nicola Girardi
*
*/

public class ListaLinked implements Lista{

	private static class Node{
		Object key;

		Node next;

		Node(Object o){
			key = o;
			next = null;
		}

	} //fine classe innestata Node

	/**
	* Testa della lista
	*/
	private Node head;

	/**
	* Numero di oggetti presenti nella lista
	*/
	private int nOgg;

	public ListaLinked(){
		head = null;
		nOgg = 0;
	}

	/**
	*@see Lista#isEmpty
	*/
	public boolean isEmpty(){
		return nOgg == 0;
	}

	/**
	*@see Lista#size
	*/
	public int size(){
		return nOgg;
	}

	/**
	*@see Lista#insert(int, java.lang.Object)
	*/
	public void insert(int k, Object o) throws IndexOutOfBoundsException{
		if(k < 0 || k > nOgg) throw new IndexOutOfBoundsException ("L'indice inserito non &egrave valido");

		Node nuovo = new Node(o);
		if(nOgg == 0){
			head = nuovo;
		}else{
			if(k == 0){
				nuovo.next = head;
				head = nuovo;
			}else{
				//nodo di appoggio che uso per scorrere i nodi
				Node indice = head;
				for(int i = 0; i < k-1; i++)
					indice = indice.next;
				indice.next = nuovo;
				nuovo.next = indice.next;
			}
		} //fine else
		nOgg++;
	}//fine metodo insert

	/**
	*@see Lista#remove(int)
	*/
	public Object remove(int k) throws IndexOutOfBoundsException{
		if(k < 0 || k > nOgg) throw new IndexOutOfBoundsException ("L'indice inserito non &egrave valido");

		Object eliminato;
		if(nOgg == 1){
			eliminato = head;
			head = null;
		}else{
			if(k == 0){
				eliminato = head.key;
				head = head.next;
			}else{
				Node indice = head;
				for(int i = 0; i < k-1; i++)
					indice = indice.next;
				eliminato = indice.next.key;
				indice.next = indice.next.next;
			}
		}
		nOgg--;
		return eliminato;
	}//fine metodo remove

	/**
	*@see get(int)
	*/
	public Object get(int k) throws IndexOutOfBoundsException{
		if(k < 0 || k > nOgg) throw new IndexOutOfBoundsException ("L'indice inserito non &egrave valido");

		Object cercato;
		if(k == 0){
			cercato = head.key;
		}else{
			Node indice = head;
			for(int i = 0; i < k-1; i++)
				indice = indice.next;
			cercato = indice.next.key;
		}
		return cercato;
	}//fine metodo get

	/**
	*@see Lista#set(int, java.lang.Object)
	*/
	public void set(int k, Object o) throws IndexOutOfBoundsException{
		if(k < 0 || k > nOgg) throw new IndexOutOfBoundsException ("L'indice inserito non &egrave valido");

		if(k == 0){
			head.key = o;
		}else{
			Node indice = head;
			for(int i = 0; i < k-1; i++)
				indice = indice.next;
			indice.next.key = o;
		}
	}//fine metodo set

}
